package com.yunhe.common.util;

import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class ObjectUtil {

    public static <S,T> T do2dto(S source, Class<T> dtoClass) {
        if (source == null) {
            return null;
        }
        Field[] fields = source.getClass().getDeclaredFields();
        try {
            T dto = dtoClass.newInstance();
            BeanUtils.copyProperties(source, dto);
            Field[] dtoFields = dto.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String typeName = field.getGenericType().getTypeName();
                if (typeName.startsWith("com.yunhe.common")) {
                    Object object = field.get(source);
                    if (object == null) {
                        continue;
                    }
                    Field[] declaredFields = object.getClass().getDeclaredFields();
                    for (Field f : declaredFields) {
                        f.setAccessible(true);
                        if ("id".equals(f.getName())) {
                            Long id = (Long) f.get(object);
                            for (Field dtoField : dtoFields) {
                                dtoField.setAccessible(true);
                                if (dtoField.getName().equals(field.getName() + "Id")) {
                                    dtoField.set(dto, id);
                                    continue;
                                }
                            }
                        } /*else if ("name".equals(f.getName())) {
                        String name = (String) f.get(object);
                        for (Field dtoField : dtoFields) {
                            if (dtoField.getName().equals(field.getName() + "Name")) {
                                dtoField.set(dto, name);
                                continue;
                            }
                        }
                    }*/ else if ("title".equals(f.getName())) {
                            String title = (String) f.get(object);
                            for (Field dtoField : dtoFields) {
                                dtoField.setAccessible(true);
                                if (dtoField.getName().equals(field.getName() + "Title")) {
                                    dtoField.set(dto, title);
                                    continue;
                                }
                            }
                        }
                    }
                }
            }
            return dto;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static <S,T> List<T> do2dto(Iterable<S> sourceList, Class<T> dtoClass) {
        List<T> result = new ArrayList<>();
        for (S source : sourceList) {
            T t = do2dto(source, dtoClass);
            if (t != null) {
                result.add(t);
            }
        }
        return result;
    }

    public static <S,T> T dto2do(S source, Class<T> doClass) {
        if (source == null) {
            return null;
        }
        Field[] fields = source.getClass().getDeclaredFields();
        try {
            T target = doClass.newInstance();
            BeanUtils.copyProperties(source, target);
            Field[] targetFields = target.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();
                for (Field targetField : targetFields) {
                    targetField.setAccessible(true);
                    if (fieldName.equals(targetField.getName() + "Id")) {
                        Object obj = Class.forName(targetField.getGenericType().getTypeName()).newInstance();
                        if (obj == null) {
                            continue;
                        }
                        Field[] declaredFields = obj.getClass().getDeclaredFields();
                        for (Field f : declaredFields) {
                            f.setAccessible(true);
                            if (f.getName().equals("id")) {
                                f.set(obj, field.get(source));
                                targetField.set(target, obj);
                                continue;
                            }
                        }
                    }/* else if (fieldName.equals(targetField.getName() + "Title")) {
                        Object obj = Class.forName(targetField.getGenericType().getTypeName()).newInstance();
                        Field[] declaredFields = obj.getClass().getDeclaredFields();
                        for (Field f : declaredFields) {
                            f.setAccessible(true);
                            if (f.getName().equals("title")) {
                                f.set(obj, field.get(source));
                                targetField.set(target, obj);
                                continue;
                            }
                        }
                    }*/
                }
            }
            return target;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static <S,T> List<T> dto2do(Iterable<S> sourceList, Class<T> doClass) {
        List<T> result = new ArrayList<>();
        for (Object source : sourceList) {
            T t = dto2do(source, doClass);
            if (t != null) {
                result.add(t);
            }
        }
        return result;
    }
}
